package com.ruoyi.server.read;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.server.enums.AddConstants5;
import com.ruoyi.server.enums.CmdConstants;
import com.ruoyi.server.enums.PullConstants3;
import com.ruoyi.server.person.MountUser;
import com.ruoyi.server.person.PassageWayUser;
import com.ruoyi.server.pkg.SendMsg;
import com.ruoyi.server.thread.ReadReceiptReader;
import com.ruoyi.server.utils.AddUtil;
import com.ruoyi.server.utils.ApplicationUtil;
import com.ruoyi.server.utils.DeleteUtil;
import com.ruoyi.server.utils.OnlineUtil;
import io.netty.channel.*;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 私人消息处理
 *
 * @author OpenACloud
 * @create 2024/6/3 21:38
 */
@Component
@ChannelHandler.Sharable
public class PrivateReader extends GroupReader {

    @Override
    protected void sendFriendOrGroupMsg(ChannelHandlerContext ctx, SendMsg sendMsg) {
        Set<Long> userFriend = ctx.attr(OnlineUtil.USER_FRIEND).get();
        if (userFriend.contains(sendMsg.RECEIVEID)) {
            SendMsg notFriendMsg = new SendMsg();
            notFriendMsg.CMD = CmdConstants.PRIVATE_CMD;
            notFriendMsg.STATUS = CmdConstants.NOT_EXIST_CMD;
            notFriendMsg.SENDID = -1L;
            notFriendMsg.CONTEXT = "好友不存在!!!!";
            notFriendMsg.TIME = LocalDateTime.now();
            ctx.channel().writeAndFlush(notFriendMsg);
            return;
        }
        sendMsg.setChannel(OnlineUtil.ONLINE_MAPS.get(sendMsg.RECEIVEID));
        if (Objects.nonNull(sendMsg.getChannel())) {
            ChannelFuture writeAndFlush = sendMsg.getChannel().channel().writeAndFlush(sendMsg);
            writeAndFlush.addListener(new ReadReceiptReader(this, sendMsg));
        } else {
            this.saveMessages(sendMsg);
        }
    }

    @Override
    protected void addFriendOrGroup(ChannelHandlerContext ctx, SendMsg sendMsg) {
        if (AddUtil.addFriend(ctx, sendMsg, AddUtil.produceReplyMsg(AddConstants5.ADD_FRIEND, -1L))) {
            redisCache.setCacheObject(AddConstants5.AP_FRIEND_MSG + sendMsg.RECEIVEID + ":" + sendMsg.SENDID, sendMsg, 10, TimeUnit.DAYS);
        }
    }

    @Override
    protected void apFriendOrGroupProcessing(ChannelHandlerContext ctx, SendMsg sendMsg) {
        if(ApplicationUtil.applicationFriend(ctx, sendMsg)) {
            friendService.addFriend(sendMsg.SENDID, sendMsg.RECEIVEID, sendMsg.RECEIVENAME);
            friendService.addFriend(sendMsg.RECEIVEID, sendMsg.SENDID, ctx.attr(OnlineUtil.PASSAGE_WAR_USER).get().getUserName());
        }
    }

    @Override
    protected void deleteFriendOrGroup(ChannelHandlerContext ctx, SendMsg sendMsg) {
        DeleteUtil.deleteFriendRsp(ctx, sendMsg);
        friendService.deleteFriend(sendMsg.SENDID, sendMsg.RECEIVEID);
        friendService.deleteFriend(sendMsg.RECEIVEID, sendMsg.SENDID);
    }

    @Override
    public void saveMessages(SendMsg sendMsg) {
        sendMsgMapper.saveMessages(sendMsg);
    }

    @Override
    public void pullMessages(ChannelHandlerContext ctx, PassageWayUser wayUser) {
        SendMsg sendMsg = new SendMsg();
        sendMsg.CMD = PullConstants3.PULL_MESSAGES;
        sendMsg.STATUS = PullConstants3.PULL_START_STATUS;
        sendMsg.SENDID = -1L;
        sendMsg.CONTEXT = "START PULL MESSAGES!!!";
        sendMsg.TIME = LocalDateTime.now();
        ctx.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(sendMsg)));
        List<SendMsg> sendMsgArrays = sendMsgMapper.pullMessages(wayUser);
        for (SendMsg sendMsgArray : sendMsgArrays) {
            ctx.channel().writeAndFlush(sendMsgArray);
        }
        super.pullMessages(ctx, wayUser);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        userService.updateUserWaterTime(ctx.attr(OnlineUtil.SEND_ID).get(), LocalDateTime.now());
        redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + ctx.attr(OnlineUtil.PASSAGE_WAR_USER).get().getToken());
    }
}
